package com.easy.config;

import com.easy.security.JwtAuthFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.config.Customizer;
//这个 SecurityConfig 的作用就是 定义安全规则，让你的应用变成一个 基于 JWT 的无状态认证系统：
//
//登录接口可以匿名访问；
//
//其他接口必须带合法的 Token 才能访问；
//
//不同角色的用户能走到不同的权限控制逻辑；
//
//出错时返回标准的 JSON（401/403），方便前端处理。
@Configuration
@EnableMethodSecurity // 如需 @PreAuthorize  启用方法级别的权限控制
public class SecurityConfig {

    private final JwtAuthFilter jwtAuthFilter;

    //通过构造函数吧JwtAuthFilter注入进来
    public SecurityConfig(JwtAuthFilter jwtAuthFilter) {
        this.jwtAuthFilter = jwtAuthFilter;
        System.out.println("SecurityConfig 已加载");
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // ⭐ 启用 CORS（会使用上面的 CorsFilter 配置）
                //允许跨域
                .cors(Customizer.withDefaults())
                //关闭 CSRF（因为我们用的是 Token，不是 Session + 表单）
                .csrf(csrf -> csrf.disable())
                //关闭 Session，改为无状态（STATELESS）
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                //定义 URL 访问规则
                .authorizeHttpRequests(auth -> auth
                        // 预检请求（CORS 的 OPTIONS 请求）必须放行
                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                        // 登录接口、公共资源允许匿名访问
                        .requestMatchers("/api/auth/**", "/public/**", "/assets/**", "/error").permitAll()
                        // 其他都需要认证
                        .anyRequest().authenticated()
                )
                // 5) 禁用默认的表单登录和退出接口（因为我们用 JWT）
                .formLogin(form -> form.disable())
                .logout(logout -> logout.disable())
                //自定义异常处理
                .exceptionHandling(ex -> ex
                        .accessDeniedHandler((request, response, e) -> {
                            response.setContentType("application/json;charset=UTF-8");
                            response.getWriter().write("{\"code\":403,\"msg\":\"权限不足\"}");
                        })
                        .authenticationEntryPoint((request, response, e) -> {
                            response.setContentType("application/json;charset=UTF-8");
                            response.getWriter().write("{\"code\":401,\"msg\":\"未登录\"}");
                        })
                )
                // ⭐ 将 JWT 过滤器挂到链上
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
}
